/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * FrmP2P.java
 *
 * Created on 9/Mar/2011, 17:28:00
 */

package p2p;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Bruno
 */
public class FrmP2P extends javax.swing.JFrame {

    /** Creates new form FrmP2P */
    public FrmP2P() {
        initComponents();
		FilesTable = (DefaultTableModel)tblFiles.getModel();
		SearchTable = (DefaultTableModel)tblSearch.getModel();
		Global.updateFilesTableThread.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        filesPopupMenu = new javax.swing.JPopupMenu();
        mnuResumeFileDownloadP = new javax.swing.JMenuItem();
        mnuPauseFileDownloadP = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        mnuRemoveFileP = new javax.swing.JMenuItem();
        searchPopupMenu = new javax.swing.JPopupMenu();
        mnuAddSearchFile = new javax.swing.JMenuItem();
        tabbedPane = new javax.swing.JTabbedPane();
        filesPane = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tblFiles = new javax.swing.JTable();
        searchPanel = new javax.swing.JPanel();
        txtSearch = new javax.swing.JTextField();
        cmdSearch = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        tblSearch = new javax.swing.JTable();
        cmdAddFile = new javax.swing.JButton();
        menu = new javax.swing.JMenuBar();
        mnuFile = new javax.swing.JMenu();
        mnuAddFile = new javax.swing.JMenuItem();
        mnuRemove = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        mnuResumeFileDownload = new javax.swing.JMenuItem();
        mnuPauseFileDownload = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        mnuExit = new javax.swing.JMenuItem();
        mnuHelp = new javax.swing.JMenu();
        mnuAbout = new javax.swing.JMenuItem();

        mnuResumeFileDownloadP.setMnemonic(KeyEvent.VK_S);
        mnuResumeFileDownloadP.setText("Resume");
        mnuResumeFileDownloadP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuResumeFileDownloadPActionPerformed(evt);
            }
        });
        filesPopupMenu.add(mnuResumeFileDownloadP);

        mnuPauseFileDownloadP.setMnemonic(KeyEvent.VK_P);
        mnuPauseFileDownloadP.setText("Pause");
        mnuPauseFileDownloadP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuPauseFileDownloadPActionPerformed(evt);
            }
        });
        filesPopupMenu.add(mnuPauseFileDownloadP);
        filesPopupMenu.add(jSeparator3);

        mnuRemoveFileP.setMnemonic(KeyEvent.VK_R);
        mnuRemoveFileP.setText("Remove");
        mnuRemoveFileP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuRemoveFilePActionPerformed(evt);
            }
        });
        filesPopupMenu.add(mnuRemoveFileP);

        mnuAddSearchFile.setText("Download");
        mnuAddSearchFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuAddSearchFileActionPerformed(evt);
            }
        });
        searchPopupMenu.add(mnuAddSearchFile);

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle(Global.name);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        tblFiles.setAutoCreateRowSorter(true);
        tblFiles.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Path", "Size", "Progress", "State"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tblFiles.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tblFiles.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tblFilesMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(tblFiles);

        javax.swing.GroupLayout filesPaneLayout = new javax.swing.GroupLayout(filesPane);
        filesPane.setLayout(filesPaneLayout);
        filesPaneLayout.setHorizontalGroup(
            filesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filesPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 543, Short.MAX_VALUE)
                .addContainerGap())
        );
        filesPaneLayout.setVerticalGroup(
            filesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filesPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 367, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabbedPane.addTab("Files", filesPane);

        txtSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtSearchActionPerformed(evt);
            }
        });

        cmdSearch.setText("Search");
        cmdSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSearchActionPerformed(evt);
            }
        });

        tblSearch.setAutoCreateRowSorter(true);
        tblSearch.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Size", "Peers"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tblSearch.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tblSearch.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tblSearchMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(tblSearch);

        cmdAddFile.setText("Download");
        cmdAddFile.setToolTipText("Download selected file.");
        cmdAddFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdAddFileActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout searchPanelLayout = new javax.swing.GroupLayout(searchPanel);
        searchPanel.setLayout(searchPanelLayout);
        searchPanelLayout.setHorizontalGroup(
            searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, searchPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 543, Short.MAX_VALUE)
                    .addGroup(searchPanelLayout.createSequentialGroup()
                        .addComponent(txtSearch, javax.swing.GroupLayout.DEFAULT_SIZE, 387, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdSearch)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdAddFile)))
                .addContainerGap())
        );
        searchPanelLayout.setVerticalGroup(
            searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(searchPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdAddFile)
                    .addComponent(cmdSearch))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabbedPane.addTab("Search", searchPanel);

        mnuFile.setMnemonic(KeyEvent.VK_F);
        mnuFile.setText("File");

        mnuAddFile.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
        mnuAddFile.setMnemonic(KeyEvent.VK_A);
        mnuAddFile.setText("Add File...");
        mnuAddFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuAddFileActionPerformed(evt);
            }
        });
        mnuFile.add(mnuAddFile);

        mnuRemove.setMnemonic(KeyEvent.VK_R);
        mnuRemove.setText("Remove file");
        mnuRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuRemoveActionPerformed(evt);
            }
        });
        mnuFile.add(mnuRemove);
        mnuFile.add(jSeparator1);

        mnuResumeFileDownload.setMnemonic(KeyEvent.VK_S);
        mnuResumeFileDownload.setText("Resume file download");
        mnuResumeFileDownload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuResumeFileDownloadActionPerformed(evt);
            }
        });
        mnuFile.add(mnuResumeFileDownload);

        mnuPauseFileDownload.setMnemonic(KeyEvent.VK_P);
        mnuPauseFileDownload.setText("Pause file download");
        mnuPauseFileDownload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuPauseFileDownloadActionPerformed(evt);
            }
        });
        mnuFile.add(mnuPauseFileDownload);
        mnuFile.add(jSeparator2);

        mnuExit.setMnemonic(KeyEvent.VK_X);
        mnuExit.setText("Exit");
        mnuExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuExitActionPerformed(evt);
            }
        });
        mnuFile.add(mnuExit);

        menu.add(mnuFile);

        mnuHelp.setMnemonic(KeyEvent.VK_H);
        mnuHelp.setText("Help");

        mnuAbout.setMnemonic(KeyEvent.VK_A);
        mnuAbout.setText("About");
        mnuAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuAboutActionPerformed(evt);
            }
        });
        mnuHelp.add(mnuAbout);

        menu.add(mnuHelp);

        setJMenuBar(menu);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 568, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
		exit(); 
    }//GEN-LAST:event_formWindowClosing

    private void mnuExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuExitActionPerformed
		exit();
    }//GEN-LAST:event_mnuExitActionPerformed

	private void mnuAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuAboutActionPerformed
		JOptionPane.showMessageDialog(null, Global.getFullName() + "\nAuthors: Bruno Nova & Rolando Pereira", "About " + Global.name, JOptionPane.INFORMATION_MESSAGE);
	}//GEN-LAST:event_mnuAboutActionPerformed

	private void mnuAddFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuAddFileActionPerformed
		addFile();
	}//GEN-LAST:event_mnuAddFileActionPerformed

	private void cmdSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSearchActionPerformed
		if(txtSearch.getText().trim().length() == 0) // exit if text field is empty
			return;

		// Lock search controls for 3 seconds
		(new Thread() {

			@Override
			public void run() {

				txtSearch.setEnabled(false);
				cmdSearch.setEnabled(false);
				try {
					Thread.sleep(3000);
				} catch (InterruptedException ex) { }
				txtSearch.setEnabled(true);
				cmdSearch.setEnabled(true);
			}
			
		}).start();

		SearchList.startSearch(txtSearch.getText()); // Start search
	}//GEN-LAST:event_cmdSearchActionPerformed

	private void txtSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtSearchActionPerformed
		cmdSearchActionPerformed(evt); // Pressing <Enter> when this text field has focus will "press" cmdSearch
	}//GEN-LAST:event_txtSearchActionPerformed

	private void mnuRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuRemoveActionPerformed
		removeSelectedFile();
	}//GEN-LAST:event_mnuRemoveActionPerformed

	private void mnuRemoveFilePActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuRemoveFilePActionPerformed
		removeSelectedFile();
	}//GEN-LAST:event_mnuRemoveFilePActionPerformed

	private void tblFilesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tblFilesMouseClicked
		if(evt.getButton() == MouseEvent.BUTTON3) // right-click
			filesPopupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
	}//GEN-LAST:event_tblFilesMouseClicked

	private void mnuResumeFileDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuResumeFileDownloadActionPerformed
		resumeDownloadSelectedFile();
	}//GEN-LAST:event_mnuResumeFileDownloadActionPerformed

	private void mnuPauseFileDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuPauseFileDownloadActionPerformed
		pauseDownloadSelectedFile();
	}//GEN-LAST:event_mnuPauseFileDownloadActionPerformed

	private void mnuResumeFileDownloadPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuResumeFileDownloadPActionPerformed
		resumeDownloadSelectedFile();
	}//GEN-LAST:event_mnuResumeFileDownloadPActionPerformed

	private void mnuPauseFileDownloadPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuPauseFileDownloadPActionPerformed
		pauseDownloadSelectedFile();
	}//GEN-LAST:event_mnuPauseFileDownloadPActionPerformed

	private void cmdAddFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdAddFileActionPerformed
		addSelectedFile();
	}//GEN-LAST:event_cmdAddFileActionPerformed

	private void mnuAddSearchFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuAddSearchFileActionPerformed
		addSelectedFile();
	}//GEN-LAST:event_mnuAddSearchFileActionPerformed

	private void tblSearchMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tblSearchMouseClicked
		if(evt.getButton() == MouseEvent.BUTTON3) // right-click
			searchPopupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
		else if(evt.getButton() == MouseEvent.BUTTON1 && evt.getClickCount() == 2) // left doubleclick
			addSelectedFile();
	}//GEN-LAST:event_tblSearchMouseClicked

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cmdAddFile;
    private javax.swing.JButton cmdSearch;
    private javax.swing.JPanel filesPane;
    private javax.swing.JPopupMenu filesPopupMenu;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JMenuBar menu;
    private javax.swing.JMenuItem mnuAbout;
    private javax.swing.JMenuItem mnuAddFile;
    private javax.swing.JMenuItem mnuAddSearchFile;
    private javax.swing.JMenuItem mnuExit;
    private javax.swing.JMenu mnuFile;
    private javax.swing.JMenu mnuHelp;
    private javax.swing.JMenuItem mnuPauseFileDownload;
    private javax.swing.JMenuItem mnuPauseFileDownloadP;
    private javax.swing.JMenuItem mnuRemove;
    private javax.swing.JMenuItem mnuRemoveFileP;
    private javax.swing.JMenuItem mnuResumeFileDownload;
    private javax.swing.JMenuItem mnuResumeFileDownloadP;
    private javax.swing.JPanel searchPanel;
    private javax.swing.JPopupMenu searchPopupMenu;
    private javax.swing.JTabbedPane tabbedPane;
    private javax.swing.JTable tblFiles;
    private javax.swing.JTable tblSearch;
    private javax.swing.JTextField txtSearch;
    // End of variables declaration//GEN-END:variables

	// Form table models
	DefaultTableModel FilesTable = null;
	DefaultTableModel SearchTable = null;

    /** Exit the program after confirmation
     */
    private void exit() {
        if(JOptionPane.showConfirmDialog(null, "Do you really want to quit " + Global.name + "?", Global.name, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
			try {
				Global.controlSocket.leaveGroup(Global.multicastInetAddr);
				Global.dataSocket.leaveGroup(Global.multicastInetAddr);
			} catch (Exception ex) {
				// Ignore
			}
            P2PFileList.deleteIncompleteFiles();
            System.exit(0);
		}
    }

	/** Add a file to share on the network.
	 */
	private void addFile() {
		// Show file dialog
		JFileChooser chooser = new JFileChooser();
		chooser.setDialogTitle("Add file");
		chooser.setMultiSelectionEnabled(true); // Multiple files can be chosen
		chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); // Only files can be selected
		int res = chooser.showOpenDialog(null);

		if(res == JFileChooser.APPROVE_OPTION) {
			// Get selected files
			File[] files = chooser.getSelectedFiles();

			// Try to add the files
			for(int i = 0; i < files.length; i++) {
				addNewFile(files[i]);
			}
		}
	}

	/** Returns the index of the selected file in the "Files" list.
	 * @return Index of the selected file in the "Files" list.
	 */
	private int getTblFilesSelectedIndex() {
		int index = tblFiles.getSelectedRow();
		if(index == -1) // no row selected
			return -1;
		return tblFiles.convertRowIndexToModel(index); // get the real index of the row in the table
	}

	/** Returns the index of the selected file in the "Search" list.
	 * @return Index of the selected file in the "Search" list.
	 */
	private int getTblSearchSelectedIndex() {
		int index = tblSearch.getSelectedRow();
		if(index == -1) // no row selected
			return -1;
		return tblSearch.convertRowIndexToModel(index); // get the real index of the row in the table
	}

	/** Change the state of the file with the specified <i>index</i> in the "Files" table to Complete.
	 * @param index Index of the file in the table (without sorting).
	 */
	public void setFileComplete(int index) {
		FilesTable.setValueAt("Complete", index, 4);
	}

	/** Removes the selected file in the "Files" list.
	 */
	private void removeSelectedFile() {
		int index = getTblFilesSelectedIndex();
		if(index == -1)
			return;

		int res = JOptionPane.showConfirmDialog(null, "Do you really want to remove " + P2PFileList.getFile(index).getName() + " from the list?", Global.name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
		if(res == JOptionPane.OK_OPTION) {
			P2PFileList.removeFile(index);
			FilesTable.removeRow(index);
		}
	}

	/** Resume downloading/sharing the selected file in the "Files" list.
	 */
	private void resumeDownloadSelectedFile() {
		int index = getTblFilesSelectedIndex();
		if(index == -1)
			return;

		P2PFile file = P2PFileList.getFile(index);
		if(file == null)
			return;

		file.resumeDownload();

		// update table text
		String text = "";
		switch(file.getState()) {
			case P2PFile.STATE_COMPLETE: text = "Complete"; break;
			case P2PFile.STATE_DOWNLOADING: text = "Downloading"; break;
			case P2PFile.STATE_PAUSED: text = "Paused"; break;
		}
		FilesTable.setValueAt(text, index, 4);
	}

	/** Stops downloading/sharing the selected file in the "Files" list.
	 */
	private void pauseDownloadSelectedFile() {
		int index = getTblFilesSelectedIndex();
		if(index == -1)
			return;

		P2PFile file = P2PFileList.getFile(index);
		if(file == null)
			return;

		file.pauseDownload();

		// update table text
		String text = "";
		switch(file.getState()) {
			case P2PFile.STATE_COMPLETE: text = "Complete"; break;
			case P2PFile.STATE_DOWNLOADING: text = "Downloading"; break;
			case P2PFile.STATE_PAUSED: text = "Paused"; break;
		}
		FilesTable.setValueAt(text, index, 4);
	}

	/** Starts downloading the selected file in the "Search" list.
	 */
	private void addSelectedFile() {
		int index = getTblSearchSelectedIndex();
		if(index == -1)
			return;

		SearchFile file = SearchList.getFile(index);
		if(file == null)
			return;

		// Ask the user where to save the file
		JFileChooser chooser = new JFileChooser();
		chooser.setDialogTitle("Specify folder to save the file");
		chooser.setMultiSelectionEnabled(false); // Only one directory can be selected
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // Only directories can be selected
		int res = chooser.showSaveDialog(null);

		if(res == JFileChooser.APPROVE_OPTION) {
			String path = chooser.getSelectedFile().getAbsolutePath() + File.separator + file.getName();

			// Ensure that the file doesn't exist
			File tmp = new File(path);
			if(tmp.exists()) {
				JOptionPane.showMessageDialog(null, "A file with the same name already exists in the specified folder!", Global.name, JOptionPane.ERROR_MESSAGE);
				return;
			}

			// Add the file to the "Files" list and start downloading
			addNewFile(file, path);
		}
	}

	/** Adds the indicated <i>file</i> in the local machine to the "Files" list.
	 * @param file File to add.
	 */
	private void addNewFile(File file) {
		// Try to add the file to the list
		P2PFile p2pfile = null;
		String name = file.getName(), path = file.getAbsolutePath();
		try {
			p2pfile = new P2PFile(file);
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, "Error adding the file " + name + "!", Global.name, JOptionPane.ERROR_MESSAGE);
			return;
		}

		if(!P2PFileList.addFile(p2pfile)) {
			JOptionPane.showMessageDialog(null, "File " + name + " already exists!", Global.name, JOptionPane.ERROR_MESSAGE);
			return;
		}


		String size_str = p2pfile.getHumanReadableSize();
		String[] values_array = new String[] {name, path, size_str, "100%", "Complete"};

		// Add the file to the table
		FilesTable.addRow(values_array);
	}

	/** Adds a remote <i>file</i> to the "Files" list, to be downloaded to the specified <i>path</i>
	 * in the local machine.
	 * @param file File to add.
	 * @param path Path to save the file in the local machine.
	 */
	private void addNewFile(SearchFile file, String path) {
		// Try to add the file to the list
		P2PFile p2pfile = null;



		try {
			p2pfile = new P2PFile(file, path);
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, "Error adding the file " + file.getName() + "!", Global.name, JOptionPane.ERROR_MESSAGE);
			return;
		}

		if(!P2PFileList.addFile(p2pfile)) {
			JOptionPane.showMessageDialog(null, "File " + file.getName() + " already exists!", Global.name, JOptionPane.ERROR_MESSAGE);
			p2pfile.deleteIfIncomplete();
			return;
		}

		p2pfile.askForChunk(); // Ask for the file (all chunks)

		String size_str = p2pfile.getHumanReadableSize();
		String[] values_array = new String[] {file.getName(), path, size_str, "0%", "Downloading"};

		// Add the file to the table
		FilesTable.addRow(values_array);

		tabbedPane.setSelectedIndex(0);
	}
}
